<script lang="ts" setup>
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { AiLlmApi } from '#/api/ai/llm/llmModel';
import type { OllamaModelApi } from '#/api/ai/llm/ollama';

import { ref } from 'vue';

import { Page, useVbenModal } from '@vben/common-ui';

import { Alert, message, Progress } from 'ant-design-vue';

import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table';
import { addAiLlm } from '#/api/ai/llm/llmModel';
import { deleteModel, getLargeModels, installModel } from '#/api/ai/llm/ollama';
import { $t } from '#/locales';
import {
  isSupportChat,
  isSupportEmbed,
  isSupportFunctionCalling,
} from '#/utils/modelUtils';

import { useGridColumns, useGridFormSchema } from './data';
import CreateForm from './modules/createForm.vue';

const installStatus = ref<'active' | 'exception' | 'success'>('active');
const progress = ref<number>(0);
const visible = ref(false);
const modelName = ref('');
const isLoading = ref(false);
const [FormModal, formModalApi] = useVbenModal({
  connectedComponent: CreateForm,
  destroyOnClose: true,
});
/** 刷新表格 */
function onRefresh() {
  gridApi.reload();
}
/** 安装模型 */
function handleCreate() {
  formModalApi.setData(null).open();
}
/** 删除模型 */
async function handleDelete(row: OllamaModelApi.OllamaModel) {
  const hideLoading = message.loading({
    content: $t('ui.actionMessage.deleting', [row.name]),
    duration: 0,
    key: 'action_process_msg',
  });
  try {
    await deleteModel({ modelName: row.name });
    message.success($t('ui.actionMessage.deleteSuccess', [row.name]));
    onRefresh();
  } finally {
    hideLoading();
  }
}
function handleSuccess(data: any) {
  modelName.value = data.modelName;
  isLoading.value = true;
  visible.value = true;
  // 调用安装模型
  const { start, stop } = installModel();
  start({
    data,
    onMessage: (msg) => {
      const retData = JSON.parse(msg); // 解析 JSON 数据
      console.log(retData);
      if (retData?.data) {
        const msgData = JSON.parse(retData.data);
        if (msgData?.error == 'pull model manifest: file does not exist') {
          installStatus.value = 'exception'; // 设置进度条状态为异常
          message.error('模型不存在');
          isLoading.value = false;
          stop();
        }
        // 如果数据中包含 completed 和 total，计算进度百分比
        if (msgData.completed !== undefined && msgData.total !== undefined) {
          const percent = Math.round((msgData.completed / msgData.total) * 100);
          progress.value = percent; // 更新进度百分比
        }
        // 如果状态是 complete，设置进度条为完成状态
        if (msgData.status === 'complete' || msgData.status === 'success') {
          progress.value = 100;
          installStatus.value = 'success'; // 设置进度条状态为完成
          isLoading.value = false; // 停止加载状态
        }
      }
    },
    onFinished: () => {
      setTimeout(() => {
        // 三秒后安装进度条消失
        visible.value = false;
      }, 3000);
    },
    onError: (err) => {
      isLoading.value = false;
    },
  });
}
// 处理行操作按钮点击事件
const handleRowAction = async (row: OllamaModelApi.OllamaModel) => {
  if (row.hasJoinModel === 1) {
    return;
  }
  await addAiLlm({
    title: `ollama_${row.name}`,
    llmEndpoint: row.apiUrl,
    llmModel: row.name,
    supportEmbed: isSupportEmbed(row.name),
    supportChat: isSupportChat(row.name),
    supportFunctionCalling: isSupportFunctionCalling(row.name),
    brand: 'ollama',
  } as AiLlmApi.AiLlm);
  onRefresh();
};
const [Grid, gridApi] = useVbenVxeGrid({
  formOptions: {
    schema: useGridFormSchema(),
  },
  gridOptions: {
    columns: useGridColumns(),
    id: 'ollama-grid',
    height: 'auto',
    keepSource: true,
    proxyConfig: {
      ajax: {
        query: async ({ page }, formValues) => {
          return await getLargeModels({
            pageNo: page.currentPage,
            pageSize: page.pageSize,
            ...formValues,
          });
        },
      },
    },
    rowConfig: {
      keyField: 'name',
      isHover: true,
    },
    toolbarConfig: {
      refresh: true,
      search: true,
    },
  } as VxeTableGridOptions<OllamaModelApi.OllamaModel>,
});
</script>
<template>
  <Page auto-content-height>
    <div v-if="visible">
      <Alert
        :message="
          isLoading
            ? `${modelName} 正在安装中...`
            : installStatus == 'success'
              ? `${modelName} 安装成功！`
              : installStatus == 'exception'
                ? `${modelName} 安装失败！`
                : ''
        "
        :type="installStatus == 'exception' ? 'warning' : 'success'"
        closable
        @close="
          () => {
            visible = false;
          }
        "
        style="margin-bottom: 16px"
      />
      <Progress :percent="progress" :status="installStatus" />
    </div>
    <FormModal @success="handleSuccess" />

    <Grid table-title="ollama模型列表">
      <template #toolbar-tools>
        <TableAction
          :actions="[
            {
              label: $t('ui.actionTitle.create', ['模型']),
              type: 'primary',
              icon: ACTION_ICON.ADD,
              auth: ['ai:ollama:install'],
              onClick: handleCreate,
            },
          ]"
        />
      </template>
      <template #actions="{ row }">
        <TableAction
          :actions="[
            {
              label: row.hasJoinModel === 1 ? '已加入模型管理' : '加入模型管理',
              type: 'link',
              disabled: row.hasJoinModel === 1,
              icon: ACTION_ICON.EDIT,
              onClick: handleRowAction.bind(null, row),
              auth: ['ai:aiLlm:save'],
            },
            {
              label: $t('common.delete'),
              type: 'link',
              danger: true,
              icon: ACTION_ICON.DELETE,
              disabled: row.hasJoinModel === 1,
              auth: ['ai:ollama:delete'],
              popConfirm: {
                title: $t('ui.actionMessage.deleteConfirm', [row.modelName]),
                confirm: handleDelete.bind(null, row),
              },
            },
          ]"
        />
      </template>
    </Grid>
  </Page>
</template>
